<?php
/**
 * This is the file to define BaseComponent.
 * 
 * @author	Justin Yoo
 * @version	0.0.1.0001
 * @package	KYR.Core
 * 
 */

//	Checks if this file is called within the framework; otherwise terminates.
if (!defined("IS_FRAMEWORK") || !IS_FRAMEWORK)	header("Location: http://".$_SERVER["HTTP_HOST"]."/error/404");

//	Imports relevant files.
require_once HANDLER_PATH."KYR.Handlers.ExceptionHandler.php";

/**
 * This is class BaseComponent that defines basic properties and methods of each class inherited.
 *
 * Defines basic properties and methods of each class inherited.
 * 
 * @author	Justin Yoo
 * @package	KYR.Core
 * @abstract
 * 
 */
abstract class BaseComponent extends BaseObject
{
	protected $controls_ = null;

	/**
	 * Initiates the BaseObject class.
	 *
	 * @access	public
	 * @param	Request	$request	Request object that contains page request details.
	 * @param	int		$objectID	Either moduleID or widgetID that calls the component.
	 * @param	string	$mappedBy	Flag whether the component is called by a module or widget.
	 * @param	int		$statusCode	Page status code.
	 *
	 */
	public function __construct($request, $objectID, $mappedBy, $statusCode = 200)
	{
		parent::__construct();

		$this->request			= $request;
		$this->existComponent	= false;
		$this->statusCode		= $statusCode;
		$this->moduleID			= null;
		$this->widgetID			= null;
		$this->mappedBy			= $mappedBy;
		switch (strtolower($mappedBy))
		{
			case "module":
				$this->moduleID = $objectID;
				break;
			case "widget":
				$this->widgetID = $objectID;
				break;
		}
		$this->componentID		= null;
		$this->controls_		= array();
		$this->handlers			= array();
	}

	/**
	 * Checks if the component exists or not.
	 *
	 * @access	protected
	 * @exception	Throws an Exception while processing a database query.
	 *
	 */
	protected function CheckComponent_()
	{
		$db	= null;
		if ($this->statusCode == 200)
		{
			try
			{
				$db = new Database("MySQL");
				$qry = "CALL cms_CheckComponent(";
				$qry .= "'".$db->Quote($this->componentName)."', ";
				$qry .= $this->moduleID.", ";
				$qry .= "'".$this->mappedBy."'";
				$qry .= ")";
				$db->Query($qry);
				$row = $db->Fetch();

				if (isset($row) && count($row) > 0)
				{
					$this->existComponent	= true;
					$this->statusCode		= 200;
					$this->componentID		= $row["componentID"];
				}
			}
			catch (Exeption $ex)
			{
				$this->statusCode	= 500;
				throw $ex;
			}
		}
	}
	
	/**
	 * Creates a set of controls to be used in templates called by the component.
	 *
	 * @access	protected
	 * @abstract
	 *
	 */
	abstract protected function CreateControls_();

	/**
	 * Sets the set of controls to be used in templates called by the component.
	 *
	 * @access	protected
	 * @param	array	$variables	Set of data generated by the component.
	 * @abstract
	 *
	 */
	abstract protected function SetControls_(&$variables);

	/**
	 * Processes the component.
	 *
	 * @access	public
	 * @param	array	$variables	Set of data to be stored by the component.
	 * @abstract
	 *
	 */
	abstract public function ProcessComponent(&$variables);
	
	/**
	 * Processes the request.
	 *
	 * @access	public
	 * @param	array	$variables	Set of data to be stored by the component.
	 * @abstract
	 *
	 */
	abstract public function ProcessRequest(&$variables);
	
	/**
	 * Processes the request.
	 *
	 * @access	public
	 * @param	array	$variables	Set of data to be stored by the component.
	 * @abstract
	 *
	 */
	abstract public function ProcessAJAX(&$variables);
	
	/**
	 * Processes the request.
	 *
	 * @access	public
	 * @param	array	$variables	Set of data to be stored by the component.
	 * @abstract
	 *
	 */
	abstract public function ProcessGetPost(&$variables);

	/**
	 * Processe the component.
	 *
	 * @access	protected
	 * @param	array	$variables	Set of data to be stored by the component.
	 * @exception					Throws an Exception while loading handlers.
	 *
	 */
	protected function ProcessComponent_(&$variables)
	{
		try
		{
			//	Loads handlers corresponding to the module.
			$this->handlers	= $this->_LoadHandlers();
		}
		catch (Exception $ex) { throw $ex; }
	}
	
	/**
	 * Loads handlers correspond to the component.
	 *
	 * @access	private
	 * @return	array	Returns the list of handlers correspond to the component.
	 * @exception		Throws an Exception while loading handlers.
	 *
	 */
	private function _LoadHandlers()
	{
		$handlers		= array();
		$handlerNames	= array();
		try
		{
			//	Gets the list of handler names based on the status code.
			if ($this->statusCode == 200)
				$handlerNames	= $this->GetObjectNames_("handler");
			else
				$handlerNames[]	= array("handler" => "ExceptionHandler");

			//	Gets the list of handlers.
			if (isset($handlerNames) && count($handlerNames) > 0)
			{
				foreach ($handlerNames as $handlerName)
				{
					$filename = HANDLER_PATH."KYR.Handlers.".$handlerName["handler"].".php";
					if (file_exists($filename))
						require_once $filename;
					else
						throw new Exception("Handler not found");

					$handler = new $handlerName["handler"]($this->request, $this->componentID, $this->statusCode);
					$handlers[$handlerName["handler"]] = $handler;
				}
			}
			else
				$handlers = null;
		}
		catch (Exception $ex) { throw $ex; }
		return $handlers;
	}

	/**
	 * Gets the list of object names to be loaded.
	 *
	 * @access	protected
	 * @param	string	$type	Name of object to be loaded.
	 * @return	array			Returns the list of object names to be loaded.
	 * @exception				Throws an Exception while processing a database query.
	 *
	 */
	protected function GetObjectNames_($type)
	{
		$names	= array();
		$db		= null;
		$qry	= null;
		try
		{
			$db = new Database("MySQL");
			$qry = "CALL cms_Get".ucwords(strtolower($type))."Names(";
			$qry .= $this->componentID;
			$qry .= ")";
			$db->Query($qry);
			//Debug::PrintScreen("h1", $qry);

			while ($name = $db->Fetch())
				$names[] = $name;
		}
		catch (Exeption $ex) { throw $ex; }
		return $names;
	}
}
?>
